﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace Firecracker.Bootstrapper.Target.Test
{
  [Replace(typeof(Program.InstantiationTest))]
  public class InstantiationTestReplace
  {
    public static int ConstructorCalls1 = 0;
    public InstantiationTestReplace(String s)
    {
      ConstructorCalls1++;
    }


    public static int ConstructorCalls2 = 0;
    public InstantiationTestReplace(String s, int test)
    {
      ConstructorCalls2++;
    }

    public static int DeleteCalls = 0;
    public void Delete()
    {
      DeleteCalls++;
    }

    public static int PerformOperationCalls = 0;
    public void PerformOperation()
    {
      PerformOperationCalls++;
    }

    public static int ItemSetterCalls = 0;
    public static int ItemGetterCalls = 0;
    public String Item
    {
      get
      {
        ItemGetterCalls++;
        return "";
      }
      set { ItemSetterCalls++; }
    }

    public static int StaticMethodCalls = 0;
    public static void StaticOperation()
    {
      StaticMethodCalls++;
    }

    public static void Reset()
    {
      ConstructorCalls1 = 0;
      ConstructorCalls2 = 0;
      PerformOperationCalls = 0;
      ItemSetterCalls = 0;
      ItemGetterCalls = 0;
      StaticMethodCalls = 0;
    }
  }

  [TestFixture]
  public class Class1
  {
    [Test]
    public void test_proper_constructor_injection_single_constructor()
    {
      InstantiationTestReplace.Reset();

      Program.InstantiateFileInfo();
      Assert.IsTrue(InstantiationTestReplace.ConstructorCalls1 == 1);
    }


    [Test]
    public void test_constructor_injection_across_multiple_constructor_types()
    {
      InstantiationTestReplace.Reset();
      Program.DistinguishBetweenDifferentConstructors();
      Assert.IsTrue(InstantiationTestReplace.ConstructorCalls2 == 2);
    }

    [Test]
    public void test_method_injection()
    {
      InstantiationTestReplace.Reset();
      Program.CheckMethodReplacement();
      Assert.IsTrue(InstantiationTestReplace.PerformOperationCalls == 1);
    }


    [Test]
    public void test_property_setter()
    {
      InstantiationTestReplace.Reset();
      Program.SetterPropertyCalled();
      Assert.IsTrue(InstantiationTestReplace.ItemSetterCalls == 1);
    }

    [Test]
    public void test_property_getter()
    {
      InstantiationTestReplace.Reset();
      Program.GetterPropertyCalled();
      Assert.IsTrue(InstantiationTestReplace.ItemGetterCalls == 1);
    }

    [Test]
    public void test_static_method_call()
    {
      InstantiationTestReplace.Reset();
      Program.StaticMethodCalled();
      Assert.IsTrue(InstantiationTestReplace.StaticMethodCalls == 1);
    }


    [Test]
    public void test_method_injection_down_hierarchy_does_not_call()
    {
      InstantiationTestReplace.Reset();
      Program.SubClassCallingOperation();
      Assert.IsTrue(InstantiationTestReplace.PerformOperationCalls == 0);
    }
  }
}
